home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / etc / init.d / alsa-utils < prev    next >
Text File  |  2009-10-20  |  10KB  |  404 lines

  1. #!/bin/sh
  2. #
  3. # alsa-utils initscript
  4. #
  5. ### BEGIN INIT INFO
  6. # Provides:          alsa-utils
  7. # Required-Start:    $remote_fs udev
  8. # Required-Stop:     $remote_fs
  9. # Default-Start:     
  10. # Default-Stop:      0 6
  11. # Short-Description: Restore and store ALSA driver settings
  12. # Description:       This script stores and restores mixer levels on
  13. #                    shutdown and bootup.On sysv-rc systems: to
  14. #                    disable storing of mixer levels on shutdown,
  15. #                    remove /etc/rc[06].d/K50alsa-utils.  To disable
  16. #                    restoring of mixer levels on bootup, rename the
  17. #                    "S50alsa-utils" symbolic link in /etc/rcS.d/ to
  18. #                    "K50alsa-utils".
  19. ### END INIT INFO
  20.  
  21. # Don't use set -e; check exit status instead
  22.  
  23. # Exit silently if package is no longer installed
  24. [ -x /sbin/alsactl ] || exit 0
  25.  
  26. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  27. MYNAME=/etc/init.d/alsa-utils
  28. export PULSE_INTERNAL=0
  29.  
  30. . /lib/lsb/init-functions
  31.  
  32. # $1 EXITSTATUS
  33. # [$2 MESSAGE]
  34. log_action_end_msg_and_exit()
  35. {
  36.     log_action_end_msg "$1" ${2:+"$2"}
  37.     exit $1
  38. }
  39.  
  40. # $1 PROGRAM
  41. executable()
  42. {
  43.     # If which is not available then we must be running before
  44.     # /usr is mounted on a system that has which in /usr/bin/.
  45.     # Conclude that $1 is not executable.
  46.     [ -x /bin/which ] || [ -x /usr/bin/which ] || return 1
  47.     which "$1" >/dev/null 2>&1
  48. }
  49.  
  50. # Wait for filesystems to show up
  51. while [ ! -d /usr/bin -o ! -d /var/lib/alsa ]; do
  52.     sleep 0.2
  53. done
  54.  
  55. executable amixer || { echo "${MYNAME}: Error: No amixer program available." >&2 ; exit 1 ; }
  56.  
  57. bugout() { echo "${MYNAME}: Programming error" >&2 ; exit 123 ; }
  58.  
  59. # $1 <card ID> | "all"
  60. restore_levels()
  61. {
  62.     [ -f /var/lib/alsa/asound.state ] || return 1
  63.     CARD="$1"
  64.     [ "$1" = all ] && CARD=""
  65.     # Assume that if alsactl prints a message on stderr
  66.     # then it failed somehow.  This works around the fact
  67.     # that alsactl doesn't return nonzero status when it
  68.     # can't restore settings for the card
  69.     if MSG="$(alsactl restore $CARD 2>&1 >/dev/null)" && [ ! "$MSG" ] ; then
  70.         return 0
  71.     else
  72.         # Retry with the "force" option.  This restores more levels
  73.         # but it results in much longer error messages.
  74.         alsactl -F restore $CARD >/dev/null 2>&1
  75.         [ -z "$CARD" ] && log_action_cont_msg "warning: 'alsactl restore' failed with error message '$MSG'"
  76.         return 1
  77.     fi
  78. }
  79.  
  80. # $1 <card ID> | "all"
  81. store_levels()
  82. {
  83.     CARD="$1"
  84.     [ "$1" = all ] && CARD=""
  85.     if MSG="$(alsactl store $CARD 2>&1)" ; then
  86.         sleep 1
  87.         return 0
  88.     else
  89.         [ -z "$CARD" ] && log_action_cont_msg "warning: 'alsactl store' failed with error message '$MSG'"
  90.         return 1
  91.     fi
  92. }
  93.  
  94. echo_card_indices()
  95. {
  96.     if [ -f /proc/asound/cards ] ; then
  97.         sed -n -e's/^[[:space:]]*\([0-7]\)[[:space:]].*/\1/p' /proc/asound/cards
  98.     fi
  99. }
  100.  
  101. filter_amixer_output()
  102. {
  103.     sed \
  104.         -e '/Unable to find simple control/d' \
  105.         -e '/Unknown playback setup/d' \
  106.         -e '/^$/d'
  107. }
  108.  
  109. # The following functions try to set many controls.
  110. # No card has all the controls and so some of the attempts are bound to fail.
  111. # Because of this, the functions can't return useful status values.
  112.  
  113. # $1 <control>
  114. # $2 <level>
  115. # $CARDOPT
  116. unmute_and_set_level()
  117. {
  118.     { [ "$2" ] && [ "$CARDOPT" ] ; } || bugout
  119.     amixer $CARDOPT -q set "$1" "$2" unmute 2>&1 | filter_amixer_output || :
  120.     return 0
  121. }
  122.  
  123. # $1 <control>
  124. # $CARDOPT
  125. mute_and_zero_level()
  126. {
  127.     { [ "$1" ] && [ "$CARDOPT" ] ; } || bugout
  128.     amixer $CARDOPT -q set "$1" "0%" mute 2>&1 | filter_amixer_output || :
  129.     return 0
  130. }
  131.  
  132. # $1 <control>
  133. # $2 "on" | "off"
  134. # $CARDOPT
  135. switch_control()
  136. {
  137.     { [ "$2" ] && [ "$CARDOPT" ] ; } || bugout
  138.     amixer $CARDOPT -q set "$1" "$2" 2>&1 | filter_amixer_output || :
  139.     return 0
  140. }
  141.  
  142. # $1 <card ID>
  143. sanify_levels_on_card()
  144. {
  145.     CARDOPT="-c $1"
  146.  
  147.     unmute_and_set_level "Front" "80%"
  148.     unmute_and_set_level "Master" "80%"
  149.     unmute_and_set_level "Master Mono" "80%"   # See Bug#406047
  150.     unmute_and_set_level "Master Digital" "80%"   # E.g., cs4237B
  151.     unmute_and_set_level "Playback" "80%"
  152.     unmute_and_set_level "Headphone" "70%"
  153.     unmute_and_set_level "PCM" "80%"
  154.     unmute_and_set_level "PCM,1" "80%"   # E.g., ess1969
  155.     unmute_and_set_level "DAC" "80%"     # E.g., envy24, cs46xx
  156.     unmute_and_set_level "DAC,0" "80%"   # E.g., envy24
  157.     unmute_and_set_level "DAC,1" "80%"   # E.g., envy24
  158.     unmute_and_set_level "Synth" "80%"
  159.     unmute_and_set_level "CD" "80%"
  160.  
  161.     mute_and_zero_level "Mic"
  162.     mute_and_zero_level "IEC958"         # Ubuntu #19648
  163.  
  164.     # Intel P4P800-MX  (Ubuntu bug #5813)
  165.     switch_control "Master Playback Switch" on
  166.     switch_control "Master Surround" on
  167.  
  168.     # Trident/YMFPCI/emu10k1:
  169.     unmute_and_set_level "Wave" "80%"
  170.     unmute_and_set_level "Music" "80%"
  171.     unmute_and_set_level "AC97" "80%"
  172.  
  173.     # DRC:
  174.     unmute_and_set_level "Dynamic Range Compression" "80%"
  175.  
  176.     # Required for HDA Intel (hda-intel):
  177.     unmute_and_set_level "Front" "80%"
  178.  
  179.     # Required for SB Live 7.1/24-bit (ca0106):
  180.     unmute_and_set_level "Analog Front" "80%"
  181.  
  182.     # Required at least for Via 823x hardware on DFI K8M800-MLVF Motherboard with kernels 2.6.10-3/4 (see ubuntu #7286):
  183.     switch_control "IEC958 Capture Monitor" off
  184.  
  185.     # Required for hardware allowing toggles for AC97 through IEC958,
  186.     #  valid values are 0, 1, 2, 3. Needs to be set to 0 for PCM1.
  187.     unmute_and_set_level "IEC958 Playback AC97-SPSA" "0"
  188.  
  189.     # Required for newer Via hardware (see Ubuntu #31784)
  190.     unmute_and_set_level "VIA DXS,0" "80%"
  191.     unmute_and_set_level "VIA DXS,1" "80%"
  192.     unmute_and_set_level "VIA DXS,2" "80%"
  193.     unmute_and_set_level "VIA DXS,3" "80%"
  194.  
  195.     # Required on some notebooks with ICH4:
  196.     switch_control "Headphone Jack Sense" off
  197.     switch_control "Line Jack Sense" off
  198.  
  199.     # Some machines need one or more of these to be on;
  200.     # others need one or more of these to be off:
  201.     #
  202.     # switch_control "External Amplifier" on
  203.     switch_control "Audigy Analog/Digital Output Jack" off
  204.     switch_control "SB Live Analog/Digital Output Jack" off
  205.     
  206.     # D1984 -- Thinkpad T61/X61
  207.     # also needed for Dell Mini 9 and Dell E series
  208.     unmute_and_set_level "Speaker" "80%"
  209.     unmute_and_set_level "Headphone" "80%"
  210.  
  211.     # Studio XPS 13 second headphone jack
  212.     unmute_and_set_level "Headphone,1" "80%"
  213.  
  214.     # HDA-Intel w/ "Digital" capture mixer (See Ubuntu #193823)
  215.     unmute_and_set_level "Digital" "80%"
  216.  
  217.     # HDA-Intel w/ Digital Mic should default to Digital mic rather than
  218.     # analog (See Ubuntu #314188)
  219.     switch_control "Digital Input Source" "Digital Mic 1"
  220.     switch_control "Digital Input Source" "Digital Mic"
  221.  
  222.     # Turn off PC Beep on hda cards that support it, see Ubuntu #331589.
  223.     mute_and_zero_level "PC Beep"
  224.  
  225.     # Analog output needs 'IEC958 Optical Raw' muted to be audible
  226.     # for some codecs (Ubuntu #408370)
  227.     switch_control "IEC958 Optical Raw" off
  228.  
  229.     return 0
  230. }
  231.  
  232. # $1 <card ID> | "all"
  233. sanify_levels()
  234. {
  235.     TTSDML_RETURNSTATUS=0
  236.     case "$1" in
  237.       all)
  238.         for CARD in $(echo_card_indices) ; do
  239.             sanify_levels_on_card "$CARD" || TTSDML_RETURNSTATUS=1
  240.         done
  241.  
  242.         ;;
  243.       *)
  244.         sanify_levels_on_card "$1" || TTSDML_RETURNSTATUS=1
  245.         ;;
  246.     esac
  247.     return $TTSDML_RETURNSTATUS
  248. }
  249.  
  250. # $1 <card ID>
  251. preinit_levels_on_card()
  252. {
  253.     CARDOPT="-c $1"
  254.  
  255.     # Silly dance to activate internal speakers by default on PowerMac
  256.     # Snapper and Tumbler
  257.     id=`cat /proc/asound/card$1/id 2>/dev/null`
  258.     if [ "$id" = "Snapper" -o "$id" = "Tumbler" ]; then
  259.         switch_control "Auto Mute" off
  260.         switch_control "PC Speaker" off
  261.         switch_control "Auto Mute" on
  262.     fi
  263. }
  264.  
  265. # $1 <card ID> | "all"
  266. preinit_levels()
  267. {
  268.     TTSDML_RETURNSTATUS=0
  269.     case "$1" in
  270.       all)
  271.         for CARD in $(echo_card_indices) ; do
  272.             preinit_levels_on_card "$CARD" || TTSDML_RETURNSTATUS=1
  273.         done
  274.         ;;
  275.       *)
  276.         preinit_levels_on_card "$1" || TTSDML_RETURNSTATUS=1
  277.         ;;
  278.     esac
  279.     return $TTSDML_RETURNSTATUS
  280. }
  281.  
  282. # $1 <card ID>
  283. mute_and_zero_levels_on_card()
  284. {
  285.     CARDOPT="-c $1"
  286.     for CTL in \
  287.         Master \
  288.         PCM \
  289.         Synth \
  290.         CD \
  291.         Line \
  292.         Mic \
  293.         "PCM,1" \
  294.         Wave \
  295.         Music \
  296.         AC97 \
  297.         "Master Digital" \
  298.         DAC \
  299.         "DAC,0" \
  300.         "DAC,1" \
  301.         Headphone \
  302.         Speaker \
  303.         Playback
  304.     do
  305.         mute_and_zero_level "$CTL"
  306.     done
  307. #    for CTL in \
  308. #        "Audigy Analog/Digital Output Jack" \
  309. #        "SB Live Analog/Digital Output Jack"
  310. #    do
  311. #        switch_control "$CTL" off
  312. #    done
  313.     return 0
  314. }
  315.  
  316. # $1 <card ID> | "all"
  317. mute_and_zero_levels()
  318. {
  319.     TTZML_RETURNSTATUS=0
  320.     case "$1" in
  321.       all)
  322.         for CARD in $(echo_card_indices) ; do
  323.             mute_and_zero_levels_on_card "$CARD" || TTZML_RETURNSTATUS=1
  324.         done
  325.         ;;
  326.       *)
  327.         mute_and_zero_levels_on_card "$1" || TTZML_RETURNSTATUS=1
  328.         ;;
  329.     esac
  330.     return $TTZML_RETURNSTATUS
  331. }
  332.  
  333.  
  334. # $1 <card ID> | "all"
  335. card_OK()
  336. {
  337.     [ "$1" ] || bugout
  338.     if [ "$1" = all ] ; then
  339.         [ -d /proc/asound ]
  340.         return $?
  341.     else
  342.         [ -d "/proc/asound/card$1" ] || [ -d "/proc/asound/$1" ]
  343.         return $?
  344.     fi
  345. }
  346.  
  347. # If a card identifier is provided in $2 then regard it as an error
  348. # if that card is not present; otherwise don't regard it as an error.
  349.  
  350. case "$1" in
  351.   start)
  352.     EXITSTATUS=0
  353.     TARGET_CARD="$2"
  354.     case "$TARGET_CARD" in
  355.       ""|all) TARGET_CARD=all ; log_action_begin_msg "Setting up ALSA" ;;
  356.     esac
  357.     if ! card_OK "$TARGET_CARD"; then
  358.         [ "$TARGET_CARD" = "all" ] && log_action_end_msg "$( [ ! "$2" ] ; echo $? ; )" "none loaded"
  359.         exit $?
  360.     fi
  361.     preinit_levels "$TARGET_CARD" || EXITSTATUS=1
  362.     if ! restore_levels "$TARGET_CARD" ; then
  363.         sanify_levels "$TARGET_CARD" || EXITSTATUS=1
  364.         restore_levels "$TARGET_CARD" >/dev/null 2>&1 || :
  365.     fi
  366.     [ "$TARGET_CARD" = "all" ] && log_action_end_msg_and_exit "$EXITSTATUS"
  367.     exit $EXITSTATUS
  368.     ;;
  369.   stop)
  370.     EXITSTATUS=0
  371.     TARGET_CARD="$2"
  372.     case "$TARGET_CARD" in
  373.       ""|all) TARGET_CARD=all ; log_action_begin_msg "Shutting down ALSA" ;;
  374.       *) log_action_begin_msg "Shutting down ALSA card ${TARGET_CARD}" ;;
  375.     esac
  376.     card_OK "$TARGET_CARD" || log_action_end_msg_and_exit "$( [ ! "$2" ] ; echo $? ; )" "none loaded"
  377.     store_levels "$TARGET_CARD" || EXITSTATUS=1
  378.     mute_and_zero_levels "$TARGET_CARD" || EXITSTATUS=1
  379.     log_action_end_msg_and_exit "$EXITSTATUS"
  380.     ;;
  381.   restart|force-reload)
  382.     EXITSTATUS=0
  383.     $0 stop || EXITSTATUS=1
  384.     $0 start || EXITSTATUS=1
  385.     exit $EXITSTATUS
  386.     ;;
  387.   reset)
  388.     TARGET_CARD="$2"
  389.     case "$TARGET_CARD" in
  390.       ""|all) TARGET_CARD=all ; log_action_begin_msg "Resetting ALSA" ;;
  391.       *) log_action_begin_msg "Resetting ALSA card ${TARGET_CARD}" ;;
  392.     esac
  393.     card_OK "$TARGET_CARD" || log_action_end_msg_and_exit "$( [ ! "$2" ] ; echo $? ; )" "none loaded"
  394.     preinit_levels "$TARGET_CARD"
  395.     sanify_levels "$TARGET_CARD"
  396.     log_action_end_msg_and_exit "$?"
  397.     ;;
  398.   *)
  399.     echo "Usage: $MYNAME {start [CARD]|stop [CARD]|restart [CARD]|reset [CARD]}" >&2
  400.     exit 3
  401.     ;;
  402. esac
  403.  
  404.